﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using EPiServer;
using EPiServer.Core;
using EPiServer.DataAccess;
using EPiServer.Security;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PageTypeBuilder;
using TemplateFoundation.Configuration;
using TemplateFoundation.PageTypes;
using TemplateFoundation.Tags;
using TemplateFoundation.Tests.Environment;
using TemplateFoundation.Tests.PageTypes;

namespace TemplateFoundation.Tests.UnitTests.Tags
{
    [TestClass]
    public class AddAndRemoveTags
    {
        [TestInitialize]
        public void Initialize()
        {
            if (PageReference.IsNullOrEmpty(Settings.Instance.TagsContainer))
            {
                PageStructure.CreateTagsContainer("Tags", PageReference.RootPage);
            }

            Settings.Instance.TagPageTypeId = PageTypeResolver.Instance.GetPageTypeID(typeof(TagsContainerPage)).Value;
        }

        [TestMethod]
        public void AddTagsUsingMultipleTagObjectsWithoutPublishing()
        {
            int numberOfTagsToAdd = 5;

            var tags = new List<string>();

            for (int i = 0; i < numberOfTagsToAdd; i++)
            {
                tags.Add("AddAndRemoveTags-" + i);
            }

            var page = (PageTypeBase)PageStructure.CreateStandardPages("My Page To Tag", PageReference.StartPage, 1).First();

            foreach (var tagName in tags)
            {
                page.Tags.Add(new Tag(tagName));
            }

            Assert.IsTrue(page.Tags.Count==0, "Were able to add tags using multiple Tag objects even though that's not supported...?");
        }

        [TestMethod]
        public void AddTagsUsingTagCollectionWithoutPublishing()
        {
            int numberOfTagsToAdd = 5;

            var tags = new List<string>();

            for (int i = 0; i < numberOfTagsToAdd; i++)
            {
                tags.Add("AddAndRemoveTags-" + i);
            }

            var page = (PageTypeBase)PageStructure.CreateStandardPages("My Page To Tag", PageReference.StartPage, 1).First();

            var tagCollection = new TagCollection();

            foreach (var tagName in tags)
            {
                tagCollection.Add(new Tag(tagName));
            }

            page.Tags = tagCollection;

            Assert.IsTrue(page.Tags.Count==numberOfTagsToAdd, "Unexpected number of tags, expected " + numberOfTagsToAdd + " but found " + page.Tags.Count);
        }

        [TestMethod]
        public void AddTagsBySettingPropertyValueToSingleTagString()
        {
            var page = (PageTypeBase)PageStructure.CreateStandardPages("My Page To Tag", PageReference.StartPage, 1).First();

            page.Property["Tags"].Value = "testtag";

            DataFactory.Instance.Save(page, SaveAction.Publish, AccessLevel.NoAccess);

            var retrievedPage = (PageTypeBase)DataFactory.Instance.GetPage(new PageReference(page.PageLink.ID));

            Assert.IsTrue(retrievedPage.Tags.Count==1, "Expected a single tag");

            Assert.IsTrue(retrievedPage.Tags.First().Name=="testtag", "Expected tag name to be 'testtag'");
        }

        [TestMethod]
        public void AddTagsBySettingPropertyValueToMultipleTagsString()
        {
            var page = (PageTypeBase)PageStructure.CreateStandardPages("My Page To Tag", PageReference.StartPage, 1).First();

            var tagNames = new[] {"testtag", "othertesttag", "athirdtesttag", "tag with spaces"};

            page.Property["Tags"].Value = string.Join("|", tagNames);

            DataFactory.Instance.Save(page, SaveAction.Publish, AccessLevel.NoAccess);

            var retrievedPage = (PageTypeBase)DataFactory.Instance.GetPage(new PageReference(page.PageLink.ID));

            Assert.IsTrue(retrievedPage.Tags.Count==tagNames.Count(), "Expected " + tagNames.Count() + " tags");
        }

        [TestMethod]
        public void AddTagsToAPageAndThenRetrieveThem()
        {
            int numberOfTagsToAdd = 5;

            var tags = new List<string>();

            for (int i = 0; i < numberOfTagsToAdd; i++)
            {
                tags.Add("AddAndRemoveTags-" + i);
            }

            var page = (PageTypeBase)PageStructure.CreateStandardPages("My Page To Tag", PageReference.StartPage, 1).First();

            var tagCollection = new TagCollection();

            foreach (var tagName in tags)
            {
                tagCollection.Add(new Tag(tagName));
            }

            page.Tags = tagCollection;

            DataFactory.Instance.Save(page, SaveAction.Publish, AccessLevel.NoAccess);

            var retrievedPage = (PageTypeBase)DataFactory.Instance.GetPage(new PageReference(page.PageLink.ID));

            Assert.IsTrue(retrievedPage.Tags.Count==numberOfTagsToAdd, "Unexpected number of tags");

            for (int i=0; i<retrievedPage.Tags.Count; i++)
            {
                Assert.IsTrue(retrievedPage.Tags.ToList()[i].Name=="AddAndRemoveTags-" + i, "Tag name mismatch");
            }
        }
    }
}
